use strict;
use warnings;
use Data::Dumper;
use Test::More 'no_plan';

use testsupport  ;

use_ok('Log');
use_ok('DBManager');

my $log = Log->instance();

$log->setlevels('DEBUG',3);

my @dbf = ( "test1.db","test2.db");
my @path = map { "t/$_" } @dbf;

map { unlink($_); } @path;

ok(! -f $path[0],"file do not exists $path[0]");
my $dbm = DBManager->new('root' => './t', 'file' => $dbf[0] );
isa_ok($dbm,'DBManager','DBManager->new');

eval {
    $dbm->init();
};
ok($@ eq '',"exception ".Dumper($@));
ok(-f $path[0],"file exists 1 ".$path[0]);

eval {
    $dbm->init();
};
ok($@ eq '',"exception ".Dumper($@));
ok(-f $path[0],"file exists 2 ".$path[0]);

$dbm->addSubject('Fabrizio','IS','greedy');
$dbm->addSubject('Daniele','IS','tall');
$dbm->addSubject('Daniele','INCREMENT','3');
$dbm->execute();

my $res_f = $dbm->getSubject("Fabrizio");
$log->xdump(3,"res_f",$res_f);
my $res_d = $dbm->getSubject("Daniele");
$log->xdump(3,"res_d",$res_d);

is($res_f->{'Fabrizio'}->{'IS'},'greedy','$res->{Fabrizio}->{IS}');
is($res_d->{'Daniele'}->{'IS'},'tall','$res->{Daniele}->{IS}');
is($res_d->{'Daniele'}->{'INCREMENT'},'3','$res->{Daniele}->{INCREMENT}');

$dbm->assert("Fabrizio",'isProgrammer');
$dbm->assert("Fabrizio",'hasAuto','Punto');
$dbm->assert("Fabrizio",'noAssertionSingle',"novalue");
$dbm->assert("Fabrizio",'noAssertionMultiple',"novalue1");
$dbm->assert("Fabrizio",'noAssertionMultiple',"novalue2");
$dbm->assert("Fabrizio",'noAssertionMultiple',"novalue3");
$dbm->assert("Daniele",'hasAuto','Fiesta');
$dbm->execute();

$res_f = $dbm->getAssertions("Fabrizio");
$log->xdump(3,'$res_f',$res_f);
$res_d = $dbm->getAssertions("Daniele");
$log->xdump(3,'$res_d',$res_d);


is($res_f->{'Fabrizio'}->{'isProgrammer'},1,'$res_f->{Fabrizio}->{isProgrammer}');
is($res_f->{'Fabrizio'}->{'hasAuto'}->{'Punto'},1,'$res_f->{Fabrizio}->{hasAuto}->{Punto}');
is($res_d->{'Daniele'}->{'hasAuto'}->{'Fiesta'},1,'$res_d->{Daniele}->{hasAuto}->{Fiesta}');

$dbm->disassert("Daniele",'hasAuto','Fiesta');
$dbm->disassert("Fabrizio",'noAssertionMultiple','novalue2');
$dbm->execute();

my $res = $dbm->getAssertions("Fabrizio","Daniele");

ok(exists($res->{'Fabrizio'}->{'noAssertionMultiple'}),'defined $res->{Fabrizio}->{noAssertionMultiple}');
ok(!exists($res->{'Fabrizio'}->{'noAssertionMultiple'}->{'novalue2'}),'not defined $res->{Fabrizio}->{noAssertionMultiple}->{novalue2}');

ok(!exists($res->{'Daniele'}),'not defined $res->{Daniele}');

$dbm->disassert("Fabrizio",'noAssertionMultiple');
$dbm->disassert("Fabrizio",'noAssertionSingle');
$dbm->execute();

$res = $dbm->getAssertions("Fabrizio");

ok( exists($res->{'Fabrizio'}),'exists $res->{Fabrizio}');
ok(!exists($res->{'Fabrizio'}->{'noAssertionMultiple'}),'no $res->{Fabrizio}->{noAssertionMultiple}');
ok(!exists($res->{'Fabrizio'}->{'noAssertionSingle'}),'no $res->{Fabrizio}->{noAssertionSingle}');

$dbm->disassert("Fabrizio");
$dbm->execute();
$res = $dbm->getAssertions("Fabrizio");
ok(!exists($res->{'Fabrizio'}),'no more $res->{Fabrizio}');

$dbm->addSubject("Fabio","IS",'person');
$dbm->assert("Fabio","isToBeCancelled",'yes');
$dbm->execute();
$res = $dbm->getAssertions("Fabio");
ok(exists($res->{'Fabio'}->{'isToBeCancelled'}->{'yes'}),'exists $res->{Fabio}->{isToBeCancelled}->{yes}');
ok(!defined($dbm->invalidated("Fabio")),"Fabio is not invalidated");

$dbm->invalidation("Fabio");
$dbm->execute();
ok(defined($dbm->invalidated("Fabio")),"Fabio is  invalidated");

$dbm->delete("Fabio");
$dbm->execute();
$res = $dbm->getAssertions("Fabio");
ok(!exists($res->{'Fabio'}),'not exists assertion $res->{Fabio}');

$res = $dbm->getSubject("Fabio");
ok(!exists($res->{'Fabio'}),'no exists subject $res->{Fabio}');


my $trace = $log->get_printable_stack();
print STDERR $trace;
$trace = $log->get_printable_filtered_stack();
print STDERR $trace;


